<?php

namespace addons\qingdong\controller;


use addons\qingdong\model\Approval;
use  addons\qingdong\model\Attendance as AttendanceModel;
use  addons\qingdong\model\AttendanceRule;
use addons\qingdong\model\AttendanceAddress;
use  addons\qingdong\model\AttendanceTime;
use  addons\qingdong\model\AttendanceCard;
use addons\qingdong\model\ExamineRecord;
use  addons\qingdong\model\AttendanceStatisc;
use addons\qingdong\model\File;
use addons\qingdong\model\Form;
use addons\qingdong\model\FormApproval;
use addons\qingdong\model\Leave;
use addons\qingdong\model\Message;
use  addons\qingdong\model\Staff;
use  addons\qingdong\model\Flow;
use think\Db;
use think\Exception;

/**
 * 考勤
 */
class Attendance extends StaffApi
{
    protected $noNeedLogin = ['autotask'];
    protected $noNeedRight = [];

    //规则列表
    public function rule_list()
    {
        $list = AttendanceRule::where([])->select();
        foreach ($list as $k => $v) {
            $address = AttendanceAddress::where([])->limit(6)->column('address');
            $list[$k]['address_info'] = '';
            if ($address) {
                $list[$k]['address_info'] = implode(',', $address);
            }
            $list[$k]['staff_info'] = '';
            $staff = Staff::where(array('id' => array('in', $v['staff_id'])))->limit(6)->column('name');
            if ($staff) {
                $list[$k]['staff_info'] = implode(',', $staff);
            }
            $time = AttendanceTime::where([])->limit(6)->select();
            $monday = false;
            $tuesday = false;
            $wednesday = false;
            $thursday = false;
            $friday = false;
            $saturday = false;
            $weekday = false;

            foreach ($time as $ks => $vs) {
                if ($vs['monday'] == 1) {
                    $monday = true;
                }
                if ($vs['tuesday'] == 1) {
                    $tuesday = true;
                }
                if ($vs['wednesday'] == 1) {
                    $wednesday = true;
                }
                if ($vs['thursday'] == 1) {
                    $thursday = true;
                }
                if ($vs['friday'] == 1) {
                    $friday = true;
                }
                if ($vs['saturday'] == 1) {
                    $saturday = true;
                }
                if ($vs['weekday'] == 1) {
                    $weekday = true;
                }

            }
            $list[$k]['time_info'] = '';
            if ($monday && $tuesday && $wednesday && $thursday && !$friday && !$saturday && !$weekday) {
                $list[$k]['time_info'] = '周一至周四';
            } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && !$saturday && !$weekday) {
                $list[$k]['time_info'] = '周一至周五';
            } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && $saturday && !$weekday) {
                $list[$k]['time_info'] = '周一至周六';
            } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && $saturday && $weekday) {
                $list[$k]['time_info'] = '周一至周日';
            } else {
                $timeArr = array(
                    $monday ? '周一' : '',
                    $tuesday ? '周二' : '',
                    $wednesday ? '周三' : '',
                    $thursday ? '周四' : '',
                    $friday ? '周五' : '',
                    $saturday ? '周六' : '',
                    $weekday ? '周日' : '',
                );
                $timeArr = array_filter($timeArr);
                if ($timeArr) {
                    $list[$k]['time_info'] = implode(',', $timeArr);
                }

            }
        }
        $this->success('请求成功', $list);
    }

    //规则详情
    public function rule_detail()
    {
        $params = $this->request->post();
        $id = $params['id'];
        if (!isset($params['id']) || !$params['id']) {
            $this->error('ID不能为空');
        }
        $list = AttendanceRule::where(['id' => $id])->find();
        if ($list) {
            $address = AttendanceAddress::where([])->limit(6)->column('address');
            $list['address_info'] = '';
            if ($address) {
                $list['address_info'] = implode(',', $address);
            }
            $list['staff_info'] = [];
            $staff = Staff::where(array('id' => array('in', $list['staff_id'])))->field('id,img,name')->select();
            if ($staff) {
                $list['staff_info'] = $staff;
            }
            $time = AttendanceTime::where([])->limit(6)->select();
            $monday = false;
            $tuesday = false;
            $wednesday = false;
            $thursday = false;
            $friday = false;
            $saturday = false;
            $weekday = false;
            $list['time_info'] = '';
            if ($time) {
                foreach ($time as $ks => $vs) {
                    if ($vs['monday'] == 1) {
                        $monday = true;
                    }
                    if ($vs['tuesday'] == 1) {
                        $tuesday = true;
                    }
                    if ($vs['wednesday'] == 1) {
                        $wednesday = true;
                    }
                    if ($vs['thursday'] == 1) {
                        $thursday = true;
                    }
                    if ($vs['friday'] == 1) {
                        $friday = true;
                    }
                    if ($vs['saturday'] == 1) {
                        $saturday = true;
                    }
                    if ($vs['weekday'] == 1) {
                        $weekday = true;
                    }

                }

                if ($monday && $tuesday && $wednesday && $thursday && !$friday && !$saturday && !$weekday) {
                    $list['time_info'] = '周一至周四';
                } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && !$saturday && !$weekday) {
                    $list['time_info'] = '周一至周五';
                } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && $saturday && !$weekday) {
                    $list['time_info'] = '周一至周六';
                } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && $saturday && $weekday) {
                    $list['time_info'] = '周一至周日';
                } else {
                    $timeArr = array(
                        $monday ? '周一' : '',
                        $tuesday ? '周二' : '',
                        $wednesday ? '周三' : '',
                        $thursday ? '周四' : '',
                        $friday ? '周五' : '',
                        $saturday ? '周六' : '',
                        $weekday ? '周日' : '',
                    );
                    $timeArr = array_filter($timeArr);
                    if ($timeArr) {
                        $list['time_info'] = implode(',', $timeArr);
                    }

                }
            }

        }

        $this->success('请求成功', $list);
    }

    //规则添加
    public function rule_add()
    {
        $params = $this->request->post();

        if (!isset($params['name']) || !$params['name']) {
            $this->error('规则名称不能为空');
        }
        if (!isset($params['staff_id']) || !$params['staff_id']) {
            $this->error('打卡人员不能为空');
        }


        $ret = array(
            'name' => $params['name'],
            'staff_id' => $params['staff_id'],
            'type' => $params['type'],
        );
        Db::startTrans();
        try {
            $result = AttendanceRule::create($ret);
            if (!$result) {
                throw new Exception('添加失败');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('添加成功');
    }

    //规则修改
    public function rule_update()
    {
        $params = $this->request->post();
        $id = $params['id'];
        if (!isset($params['id']) || !$params['id']) {
            $this->error('ID不能为空');
        }
        if (!isset($params['name']) || !$params['name']) {
            $this->error('规则名称不能为空');
        }
        if (!isset($params['staff_id']) || !$params['staff_id']) {
            $this->error('打卡人员不能为空');
        }

        $ret = array(
            'name' => $params['name'],
            'staff_id' => $params['staff_id'],
            'type' => $params['type'],
        );
        Db::startTrans();
        try {

            $result = AttendanceRule::where(array('id' => $id))->update($ret);
            if ($result === false) {
                throw new Exception('修改失败');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('修改成功');
    }

    //规则删除
    public function rule_dels()
    {
        $params = $this->request->post();
        $id = $params['id'];
        if (!isset($params['id']) || !$params['id']) {
            $this->error('ID不能为空');
        }

        $ret = array(
            'updatetime' => time(),
            'deletetime' => time(),
        );
        Db::startTrans();
        try {

            $result = AttendanceRule::where(array('id' => $id))->update($ret);

            if (!$result) {
                throw new Exception('删除失败');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('修改成功');
    }

    //时间段列表
    public function time_list()
    {
        $list = AttendanceTime::where([])->select();

        $datainfo = [];
        $number = '';
        $timeR = '';
        $kinfo = 0;
        foreach ($list as $k => $v) {
            $monday = false;
            $tuesday = false;
            $wednesday = false;
            $thursday = false;
            $friday = false;
            $saturday = false;
            $weekday = false;
            if ($v['monday'] == 1) {
                $monday = true;
            }
            if ($v['tuesday'] == 1) {
                $tuesday = true;
            }
            if ($v['wednesday'] == 1) {
                $wednesday = true;
            }
            if ($v['thursday'] == 1) {
                $thursday = true;
            }
            if ($v['friday'] == 1) {
                $friday = true;
            }
            if ($v['saturday'] == 1) {
                $saturday = true;
            }
            if ($v['weekday'] == 1) {
                $weekday = true;
            }
            $time_info = '';

            $timeR = $v['start_time'];
            if ($number != $v['number']) {
                if ($monday && $tuesday && $wednesday && $thursday && !$friday && !$saturday && !$weekday) {
                    $time_info = '周一至周四';
                } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && !$saturday && !$weekday) {
                    $time_info = '周一至周五';
                } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && $saturday && !$weekday) {
                    $time_info = '周一至周六';
                } elseif ($monday && $tuesday && $wednesday && $thursday && $friday && $saturday && $weekday) {
                    $time_info = '周一至周日';
                } else {
                    $timeArr = array(
                        $monday ? '周一' : '',
                        $tuesday ? '周二' : '',
                        $wednesday ? '周三' : '',
                        $thursday ? '周四' : '',
                        $friday ? '周五' : '',
                        $saturday ? '周六' : '',
                        $weekday ? '周日' : '',
                    );
                    $timeArr = array_filter($timeArr);
                    if ($timeArr) {
                        $time_info = implode(',', $timeArr);
                    }

                }
                $datainfo[] = array(
                    'number' => $v['number'],
                    'week' => $time_info,
                    'time' => $timeR . '-' . $v['end_time'],
                );
                $kinfo = $k;
            } else {
                $datainfo[$kinfo]['time'] = $timeR . '-' . $v['end_time'];
            }
            $number = $v['number'];
        }


        $this->success('请求成功', $datainfo);
    }

    //时间段详情
    public function time_detail()
    {
        $params = $this->request->post();
        if (!isset($params['number']) || !$params['number']) {
            $this->error('参数不正确');
        }
        $list = AttendanceTime::where(array('number' => $params['number']))->select();
        $data = [];
        $time = [];
        if ($list) {
            foreach ($list as $k => $v) {
                $time[] = array(
                    'start_time' => $v['start_time'],
                    'end_time' => $v['end_time'],
                    'ustart_time' => $v['ustart_time'],
                    'uend_time' => $v['uend_time'],
                    'dstart_time' => $v['dstart_time'],
                    'dend_time' => $v['dend_time'],
                    'start_status' => $v['start_status'],
                    'end_status' => $v['end_status'],
                    'start_next' => $v['start_next'],
                    'end_next' => $v['end_next'],
                );
            }
            $settime = '';
            if ($time) {
                $count = count($time);
                if ($time[0]['start_next'] == 1) {
                    $set_starttime = '次日' . $time[0]['start_time'];
                } else {
                    $set_starttime = $time[0]['start_time'];
                }
                if ($time[$count - 1]['end_next'] == 1) {
                    $set_endtime = '次日' . $time[$count - 1]['end_time'];
                } else {
                    $set_endtime = $time[$count - 1]['end_time'];
                }
                $settime = $set_starttime . '-' . $set_endtime;
            }
            $data = array(
                'number' => $params['number'],
                'time' => $time,
                'settime' => $settime,

                'monday' => $list[0]['monday'],
                'tuesday' => $list[0]['tuesday'],
                'wednesday' => $list[0]['wednesday'],
                'thursday' => $list[0]['thursday'],
                'friday' => $list[0]['friday'],
                'saturday' => $list[0]['saturday'],
                'weekday' => $list[0]['weekday'],
            );
        }

        $this->success('请求成功', $data);
    }

    //时间段增加
    public function time_add()
    {
        $params = $this->request->post();
        if (!isset($params['time']) || !$params['time'] || !is_array($params['time'])) {
            //    $this->error('请设置打卡时段');
        }

        $number = time() . rand(11111, 99999);
        $resultTime = false;
        foreach ($params['time'] as $k => $v) {
            $rettime = array(
                'number' => $number,
                'start_time' => $v['start_time'],
                'end_time' => $v['end_time'],
                'ustart_time' => $v['ustart_time'],
                'uend_time' => $v['uend_time'],
                'dstart_time' => $v['dstart_time'],
                'dend_time' => $v['dend_time'],
                'start_status' => $v['start_status'],
                'end_status' => $v['end_status'],
                'start_next' => $v['start_next'],
                'end_next' => $v['end_next'],
                'monday' => $params['monday'],
                'tuesday' => $params['tuesday'],
                'wednesday' => $params['wednesday'],
                'thursday' => $params['thursday'],
                'friday' => $params['friday'],
                'saturday' => $params['saturday'],
                'weekday' => $params['weekday'],
            );
            $resultTime = AttendanceTime::create($rettime);
            $ids[] = AttendanceTime::getLastInsID();

        }

        if (!$resultTime) {
            $this->error('添加失败');
        }
        $this->success('添加成功', ['id' => implode(',', $ids)]);
    }

    //时间段修改
    public function time_update()
    {
        $params = $this->request->post();
        if (!isset($params['number']) || !$params['number']) {
            $this->error('时间段编号不能为空');
        }
        if (!isset($params['time']) || !$params['time'] || !is_array($params['time'])) {
            $this->error('请设置打卡时段');
        }
        AttendanceTime::where(['number' => $params['number']])->update(array('deletetime' => time()));
        $number = time() . rand(11111, 99999);
        $resultTime = false;
        foreach ($params['time'] as $k => $v) {
            $rettime = array(
                'number' => $number,
                'start_time' => $v['start_time'],//开始时间
                'end_time' => $v['end_time'],//结束时间
                'ustart_time' => $v['ustart_time'],//可打卡开始时间
                'uend_time' => $v['uend_time'],//可打卡结束时间
                'dstart_time' => $v['dstart_time'],//下班可打卡开始时间
                'dend_time' => $v['dend_time'],//下班可打卡结束时间
                'start_next' => $v['start_next'],//0:非次日   1：次日
                'end_next' => $v['end_next'],//0:非次日   1：次日
                'start_status' => $v['start_status'],//上班打卡0:开启 1：关闭
                'end_status' => $v['end_status'],//下班打卡0:开启 1：关闭
                'monday' => $params['monday'],//周一  0未选择 1：已选择
                'tuesday' => $params['tuesday'],
                'wednesday' => $params['wednesday'],
                'thursday' => $params['thursday'],
                'friday' => $params['friday'],
                'saturday' => $params['saturday'],
                'weekday' => $params['weekday'],//周日
            );
            $resultTime = AttendanceTime::create($rettime);
            $ids[] = AttendanceTime::getLastInsID();
        }
        $rule = AttendanceRule::where([])->find();
        if ($rule) {
//            AttendanceRule::where(array('id' => ['egt', 1]))->update(array('time_id' => implode(',', $ids)));
        }
        if (!$resultTime) {
            $this->error('修改失败');
        }
        $this->success('修改成功', ['id' => implode(',', $ids)]);
    }

    //时间段删除
    public function time_del()
    {
        $params = $this->request->post();
        if (!isset($params['number']) || !$params['number']) {
            $this->error('参数不正确');
        }
        $number = $params['number'];

        $resultTime = AttendanceTime::where(array('number' => $number))->update(array('deletetime' => time()));
        if (!$resultTime) {
            $this->error('删除失败');
        }
        $this->success('删除成功');
    }

    //星期是否设置
    public function is_week()
    {
        $list = AttendanceTime::where([])->select();
        $monday = 0;
        $tuesday = 0;
        $wednesday = 0;
        $thursday = 0;
        $friday = 0;
        $saturday = 0;
        $weekday = 0;
        foreach ($list as $k => $v) {
            if ($v['monday'] == 1) {
                $monday = 1;
            }
            if ($v['tuesday'] == 1) {
                $tuesday = 1;
            }
            if ($v['wednesday'] == 1) {
                $wednesday = 1;
            }
            if ($v['thursday'] == 1) {
                $thursday = 1;
            }
            if ($v['friday'] == 1) {
                $friday = 1;
            }
            if ($v['saturday'] == 1) {
                $saturday = 1;
            }
            if ($v['weekday'] == 1) {
                $weekday = 1;
            }

        }
        $data = array(
            'monday' => $monday,
            'tuesday' => $tuesday,
            'wednesday' => $wednesday,
            'thursday' => $thursday,
            'friday' => $friday,
            'saturday' => $saturday,
            'weekday' => $weekday,
        );


        $this->success('请求成功', $data);
    }

    //地址列表
    public function address_list()
    {
        $list = AttendanceAddress::where([])->select();
        $this->success('请求成功', $list);
    }

    //地址详情
    public function address_detail()
    {
        $params = $this->request->post();
        if (!isset($params['id']) || !$params['id']) {
            $this->error('参数不正确');
        }
        $list = AttendanceAddress::where(array('id' => ['in', $params['id']]))->find();
        $this->success('请求成功', $list);
    }

    //地址增加
    public function address_add()
    {
        $params = $this->request->post();
        if (!$params['address']) {
            $this->error('地址不能为空');
        }
        if (!$params['distance']) {
            $this->error('距离不能为空');
        }
        if (!$params['lng'] || !$params['lat']) {
            $this->error('经纬度不能为空');
        }
        $retaddr = array(
            'address' => $params['address'],
            'address_detail' => $params['address_detail'],
            'distance' => $params['distance'],
            'lng' => $params['lng'],
            'lat' => $params['lat'],
        );
        $resultAddr = AttendanceAddress::create($retaddr);
        if (!$resultAddr) {
            $this->error('添加失败');
        }
        $id = AttendanceAddress::getLastInsID();
        $this->success('添加成功', ['id' => $id]);
    }

    //地址修改
    public function address_update()
    {
        $params = $this->request->post();
        if (!$params['id']) {
            $this->error('参数不正确');
        }
        if (!$params['address']) {
            $this->error('地址不能为空');
        }
        if (!$params['distance']) {
            $this->error('距离不能为空');
        }
        if (!$params['lng'] || !$params['lat']) {
            $this->error('经纬度不能为空');
        }
        $retaddr = array(
            'address' => $params['address'],
            'address_detail' => $params['address_detail'],
            'distance' => $params['distance'],
            'lng' => $params['lng'],
            'lat' => $params['lat'],
        );
        $resultAddr = AttendanceAddress::where(array('id' => $params['id']))->update($retaddr);
        if (!$resultAddr) {
            $this->error('修改失败');
        }
        $this->success('修改成功');
    }

    //地址删除
    public function address_del()
    {
        $params = $this->request->post();
        if (!isset($params['id']) || !$params['id']) {
            $this->error('参数不正确');
        }
        $id = $params['id'];
        $resultTime = AttendanceAddress::where(array('id' => $id))->update(array('deletetime' => time()));
        if (!$resultTime) {
            $this->error('删除失败');
        }
        $this->success('删除成功');
    }

    /**
     * 打卡
     */
    public function card_add()
    {
        $params = $this->request->post();
        if (!isset($params['type'])) { //0:上下班 1：外出
            $this->error('类型不能为空');
        }
        if (!$params['lng'] || !$params['lat']) {
            $this->error('经纬度不能为空');
        }
        //判断距离
        $address = AttendanceAddress::where([])->select();
        $disinfo = false;
        foreach ($address as $k => $v) {
            $distance = getdistance($params['lng'], $params['lat'], $v['lng'], $v['lat']);
            if ($v['distance'] >= $distance) {
                $disinfo = true;
                $address = $v['address'];
            }
        }
        if (!$disinfo) {
            $this->error('您不在打卡范围');
        }
        $id = input('id', 0, 'intval');
        $find = AttendanceStatisc::where(['id' => $id])->find();
        if (empty($find)) {
            $this->error('打卡信息不存在');
        }
        //判断打卡是否为次日
        $today = AttendanceStatisc::where(['time' => $find['time']])->select();
        $today = collection($today)->toArray();
        $start = $today[0]['ustart_time'];
        $nowtime = time();
        //当天首次打卡时间
        $todaytime1 = strtotime($find['time'] . $start);

        //上班
        $s1 = strtotime($find['time'] . $find['start_time']);
        //下班打卡
        $s2 = strtotime($find['time'] . $find['end_time']);
        $s1 = ($s1 < $todaytime1) ? $s1 + 86400 : $s1;//是否为次日
        $s2 = ($s2 < $todaytime1) ? $s2 + 86400 : $s2;//

        //早退
        $staff = Staff::info();
        $row = array(
            'staff_id' => $staff->id,
            'statisc_id' => $id,
            'type' => $params['type'],
            'time' => date('Y-m-d H:i:s'),
            'address' => $address,
            'type_name' => $params['type_name'],
            'lng' => $params['lng'],
            'lat' => $params['lat'],
            'remarks' => $params['remarks']??'',
            'file_ids' => $params['file_ids']??'',

        );
        Db::startTrans();
        try {
            $statisc = new AttendanceStatisc();
            if ($params['type'] == 0) {//上下班打卡
                if ($params['type_name'] == 0) {//上班打卡
                    if ($nowtime > $s1) {
                        $clock_in_status=3;//迟到
                        $row['late'] = 1;//迟到
                        $row['late_time'] = intval(($nowtime - $s1) / 60);//分
                    } else {
                        $row['late'] = 0;
                        $row['late_time'] = 0;
                        $clock_in_status=0;//正常
                    }
                    $statisc->save(['clock_in' => date('Y-m-d H:i:s'),
                        'clock_in_status'=>$clock_in_status,
                        'late_time' => $row['late_time']], ['id' => $id]);
                } elseif ($params['type_name'] == 1) {//下班打卡
                    if ($nowtime < $s2) {
                        $row['leaver'] = 1;//早退
                        $row['leaver_time'] = intval(($s2 - $nowtime) / 60);//分
                        $clock_out_status=3;
                    } else {
                        $row['leaver'] = 0;
                        $row['leaver_time'] = 0;
                        $clock_out_status=0;
                    }
                    $statisc->save(['clock_out' => date('Y-m-d H:i:s'),
                        'clock_out_status'=>$clock_out_status,
                        'leaver_time' => $row['leaver_time']], ['id' => $id]);
                }
            }
            $model = new AttendanceModel();
            $result = $model->save($row);
            $row['id'] = $model->id;
            if (!$result) {
                throw new Exception('打卡失败');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }


        $this->success('打卡成功', $row);
    }

    /**
     * 获取打卡详情
     */
    public function get_attendance_detail(){
        $id=input('id',0,'intval');

        $cards=AttendanceModel::where(['id'=>$id])->order('id desc')->with(['createStaff'])->find();
        if($cards['file_ids']){
            $cards['file_ids'] = File::where(['id' => ['in', $cards['file_ids']]])
                ->field('id,types,name,file_path')->select();
        }

        //标记通知已读
        Message::setRead(Message::CARD_TYPE, $id, $this->auth->id);

        $this->success('请求成功',$cards);
    }
    /**
     * 外勤打卡
     */
    public function other_card()
    {
        $params = $this->request->post();
        if (!isset($params['type'])) { //0:上下班 1：外出
            $this->error('类型不能为空');
        }
        if (!$params['lng'] || !$params['lat']) {
            $this->error('经纬度不能为空');
        }

        $staff = Staff::info();
        $row = array(
            'staff_id' => $staff->id,
            'type' => $params['type'],
            'time' => date('Y-m-d H:i:s'),
            'address' => $params['address'],
            'type_name' => $params['type_name'],
            'lng' => $params['lng'],
            'lat' => $params['lat'],
            'remarks' => $params['remarks']??'',
            'file_ids' => $params['file_ids']??'',
        );
        Db::startTrans();
        try {
            $result = AttendanceModel::create($row);
            if (!$result) {
                throw new Exception('打卡失败');
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }


        $this->success('打卡成功', $row);
    }

    /**
     * 补卡
     */
    public function card_late()
    {
        $params = $this->request->post();
        if (empty($params['statisc_id'])) {
            $this->error('打卡ID不能为空');
        }
        if (empty($params['title'])) {
            $this->error('补卡原因不能为空');
        }
        if (empty($params['time'])) {
            $this->error('补卡时间不能为空');
        }
        if (empty($params['remark'])) {
            $this->error('补卡事由不能为空');
        }
        $ret = array(
            'statisc_id' => $params['statisc_id'],
            'type' => $params['type'],
            'time' => $params['time'],
            'remark' => $params['remark'],
            'file_ids' => $params['file_ids'],
        );

        $staff = Staff::info();
        if (!empty($staff)) {
            $ret['create_staff_id'] = $staff->id;
        }

        $flow = Flow::getsteplist(Flow::CARD_STATUS);
        if (!$flow) {
            $this->error('请先配置补卡审批流');
        }
        $ret['flow_id'] = $flow['flow_id'];
        $ret['order_id'] = $flow['order_id'];
        if ($flow['status'] == 0) {//发起人自选
            $ret['flow_staff_ids'] = trim($params['flow_staff_ids']);
        } else {
            $ret['flow_staff_ids'] = trim($flow['flow_staff_ids']);
        }
        Db::startTrans();
        try {
            $result = AttendanceCard::create($ret);
            if (!$result) {
                throw new Exception('补卡失败');
            }

            $lastId = AttendanceCard::getLastInsID();
            if ($flow['status'] == 1) {//固定审批
                if (empty($params['flow_staff_ids'])) {
                    throw new Exception('审批人必须选择');
                }
                //发送审批通知
                Flow::sendStepRecord($flow, Flow::CARD_STATUS, $lastId);
            } else {//发起人自选 依次审批
                $staff_id = explode(',', $params['flow_staff_ids'])[0];
                if ($staff_id) {
                    ExamineRecord::addExaminse(ExamineRecord::CARD_TYPE, $lastId, $staff_id);
                }
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('补卡成功');
    }

    /**
     * 获取补卡记录
     */
    public function get_card_late(){
        $limit = input("limit/d", 10);

        $cards=AttendanceCard::where(['create_staff_id'=>$this->auth->id])->order('id desc')->with(['createStaff'])->paginate($limit);

        $this->success('请求成功',$cards);
    }

    /**
     * 获取补卡详情
     */
    public function get_card_detail(){
        $id=input('id',0,'intval');

        $cards=AttendanceCard::where(['id'=>$id])->order('id desc')->with(['createStaff'])->find();
        $cards['file_ids'] = File::where(['id' => ['in', explode(',', $cards['file_ids'])]])->field('id,types,name,file_path')->select();

        //标记通知已读
        Message::setRead(Message::CARD_TYPE, $id, $this->auth->id);

        $this->success('请求成功',$cards);
    }
    /*
     * 获取考勤详情
     */
    public function get_statisc()
    {
        $statisc_id = input('statisc_id');
        $statisc = AttendanceStatisc::where(['id' => $statisc_id])->find();
        if (empty($statisc)) {
            $this->error('数据不存在');
        }

        $this->success('请求成功', $statisc);
    }

    /**
     * 是否可以打卡
     */
    public function is_card()
    {
        $params = $this->request->post();
        if (!$params['lng'] || !$params['lat']) {
            $this->error('经纬度不能为空');
        }
        //判断距离
        $address = AttendanceAddress::where([])->select();
        $disinfo = false;
        foreach ($address as $k => $v) {
            $distance = getdistance($params['lng'], $params['lat'], $v['lng'], $v['lat']);
            if ($v['distance'] >= $distance) {
                $disinfo = true;
            }
        }
        if (!$disinfo) {
            $this->success('请求成功', ['is_card' => 0, 'msg' => '不在打卡范围内!']);
        }
        //判断打卡是否为次日
        $today = AttendanceStatisc::where(['time' => date('Y-m-d')])->select();
        $today = collection($today)->toArray();
        if (empty($today)) {
            $this->success('请求成功', ['is_card' => 0, 'msg' => '不在打卡范围内!!']);
        }
        $start = $today[0]['ustart_time'];
        $nowtime = time();
        //当天首次打卡时间
        $todaytime1 = strtotime(date('Y-m-d ') . $start);
        if ($nowtime < $todaytime1) {//如果小于开始打卡时间 说明是次日
            $clockDate = date('Y-m-d ', strtotime('-1 day'));
        } else {
            $clockDate = date('Y-m-d ');
        }
        $staff = Staff::info();
        //判断是否打卡时间 0未选择 1：已选择
        $statisc = AttendanceStatisc::where(['time' => $clockDate, 'staff_id' => $staff->id])->select();
        $statisc = collection($statisc)->toArray();
        if (empty($statisc)) {
            $this->success('请求成功', ['is_card' => 0, 'msg' => '不在打卡时间范围内!']);
        }
        $intime = null;
        $is_end = null;
        foreach ($statisc as $v) {
            //上班
            $s1 = strtotime($clockDate . $v['ustart_time']);
            $s2 = strtotime($clockDate . $v['uend_time']);
            //下班打卡
            $d1 = strtotime($clockDate . $v['dstart_time']);
            $d2 = strtotime($clockDate . $v['dend_time']);

            $s1 = ($s1 < $todaytime1) ? $s1 + 86400 : $s1;//是否为次日
            $s2 = ($s2 < $todaytime1) ? $s2 + 86400 : $s2;//是否为次日

            if ($nowtime >= $s1 && $nowtime <= $s2 && $v['start_status'] == 0) {

                if (empty($v['clock_in'])) {
                    $intime = ['type' => '上班打卡', 'time' => $v['start_time'], 'id' => $v['id'],
                        'text' => "请在{$v['start_time']}之前打卡", 'type_name' => 0];
                    break;
                }
            }
            $d1 = ($d1 < $todaytime1) ? $d1 + 86400 : $d1;//是否为次日
            $d2 = ($d2 < $todaytime1) ? $d2 + 86400 : $d2;//是否为次日

            if ($nowtime >= $d1 && $nowtime <= $d2 && $v['end_status'] == 0) {
                $e = strtotime($clockDate . $v['end_time']);
                $e = ($e < $todaytime1) ? $e + 86400 : $e;//是否为次日
                if ($e > $nowtime) {
                    $is_leaver = $e - $nowtime;
                } else {
                    $is_leaver = 0;
                }
                if (empty($v['clock_out'])) {
                    $intime = ['type' => '下班打卡', 'time' => $v['end_time'], 'id' => $v['id'], 'is_leaver' => $is_leaver,
                        'text' => "请在{$v['end_time']}之后打卡", 'type_name' => 1];
                    break;
                }
            }
            if ((empty($v['clock_in']) || empty($v['clock_out'])) && empty($is_end)) {
                $is_end = $v;
            }
        }
        if (!empty($is_end) && empty($intime)) {//还需要打卡 且没有打卡
            if (empty($is_end['clock_in'])) {
                $this->success('请求成功', ['is_card' => 0, 'msg' => '不在上班打卡时间范围内!!']);
            } else {
                $this->success('请求成功', ['is_card' => 0, 'msg' => '不在下班打卡时间范围内!!']);
            }
        }
        if (empty($intime)) {
            //最后一次打卡
            $attendance = AttendanceModel::where([
                'staff_id' => $staff->id,
                'time' => ['like', date('Y-m-d') . '%']])->order('id desc')->find();
            $this->success('请求成功', ['is_card' => 2, 'msg' => '今日打卡已完成',
                'intime' => $intime, 'attendance' => $attendance]);
        }

        $this->success('请求成功', ['is_card' => 1, 'msg' => '您已在打卡范围内', 'intime' => $intime]);
    }

    /**
     * 统计
     */
    public function statistics()
    {
        $date = input('date');
        if (empty($date)) {
            $this->error('日期不存在');
        }
        $staff = Staff::info();
        $date = date('Y-m-d', strtotime($date));
        $staff_id = $staff->id;

        $statisc = AttendanceStatisc::where(['time' => $date, 'staff_id' => $staff_id])->select();
        $other = AttendanceModel::where(['type' => 1, 'staff_id' => $staff_id,
            'time' => ['like', "{$date}%"]])->select();

        $this->success('请求成功', ['statisc' => $statisc, 'other' => $other]);
    }

    /**
     * 月统计
     */
    public function month_statistics()
    {
        $month = input('month');
        if (empty($month)) {
            $this->error('月统计不存在');
        }
        $month = date('Y-m', strtotime($month));
        $staff = Staff::info();
        $statisc = AttendanceStatisc::where(['time' => ['like', "{$month}%"], 'staff_id' => $staff->id])->select();
        $data = [];
        foreach ($statisc as $v) {
            $data[$v['time']][] = [
                'clock_in' => $v['clock_in'],//上班打卡
                'leaver_time' => $v['leaver_time'],
                'clock_out' => $v['clock_out'],
                'late_time' => $v['late_time'],//迟到时间
                'start_time' => $v['start_time'],
                'end_time' => $v['end_time'],
            ];
        }
        $leave = 0;//早退
        $leave_time = 0;//早退时间
        $late = 0;//迟到
        $late_time = 0;//迟到时间
        $work = 0;//旷工
        $work_time = 0;//旷工时间
        $card = 0;//缺卡
        $normal = 0;//正常
        $error = 0;//异常
        $overtime=0;//加班
        foreach ($data as $day => $time) {
            $is_normal = 1;//正常
            $is_error = 0;//异常
            foreach ($time as $t) {
                if (empty($t['clock_in']) && !empty($t['clock_out'])) {//缺卡
                    $card += 1;
                }
                if (empty($t['clock_out']) && !empty($t['clock_in'])) {//缺卡
                    $card += 1;
                }
                if (empty($t['clock_in']) && empty($t['clock_out'])) {
                    $work += 1;
                    $end_time = strtotime(date('Y-m-d ') . $v['end_time']);
                    $start_time = strtotime(date('Y-m-d ') . $v['start_time']);
                    $end_time = $end_time > $start_time ? $end_time : $end_time + 86400;
                    //旷工时长
                    $wtime = intval(($end_time - $start_time) / 60);
                    $work_time += $wtime;
                }
                if ($t['leaver_time'] > 0) {//早退
                    $leave += 1;
                    $leave_time += $t['leaver_time'];
                }
                if ($t['late_time'] > 0) {//迟到
                    $late += 1;
                    $late_time += $t['late_time'];
                }

                if (empty($t['clock_in']) || empty($t['clock_out'])
                    || $t['late_time'] != 0 || $t['leaver_time'] != 0) {//不正常卡
                    $is_normal = 0;
                    $is_error = 1;
                }

                //工作日加班
                if ($t['clock_out'] && $leave_time == 0) {
                    $clock_out = strtotime($t['clock_out']);
                    $date = date('Y-m-d ', $clock_out);
                    $end_time = $date . $t['end_time'];
                    $end_time = strtotime($end_time);
                    if ($end_time < $clock_out) {
                        $end_time = $end_time + 86400;
                    }
                    $overtime += intval(($end_time - $clock_out) / 60);
                }
            }
            if ($is_normal == 1) {
                $normal += 1;
            }
            if ($is_error == 1) {
                $error += 1;
            }
        }
        //外勤
        $other = AttendanceModel::where(['type' => 1, 'staff_id' => $staff->id, 'time' => ['like', "{$month}%"]])->count();

        $this->success('请求成功', [
            'leave' => $leave,
            'leave_time' => $leave_time,
            'late' => $late,
            'late_time' => $late_time,
            'work' => $work,
            'work_time' => $work_time,
            'card' => $card,
            'normal' => $normal,
            'error' => $error,
            'other' => $other,
            'overtime' => $overtime,
        ]);
    }

    /**
     * 日统计
     */
    public function day_statistics(){
        $month = input('month');
        $type=input('type');//类型 leave 早退 late 迟到  work 旷工 card 缺卡
        if (empty($month)) {
            $this->error('月统计不存在');
        }
        if (empty($type)) {
            $this->error('类型不存在');
        }
        $month = date('Y-m', strtotime($month));
        $staff = Staff::info();
        $statisc = AttendanceStatisc::where(['time' => ['like', "{$month}%"], 'staff_id' => $staff->id])->select();
        $data = [];
        foreach ($statisc as $v) {
            $data[$v['time']][] = [
                'clock_in' => $v['clock_in'],//上班打卡
                'leaver_time' => $v['leaver_time'],
                'clock_out' => $v['clock_out'],
                'late_time' => $v['late_time'],//迟到时间
                'start_time' => $v['start_time'],
                'end_time' => $v['end_time'],
            ];
        }
        $result=[];
        foreach ($data as $day=>$time) {

            $leave = 0;//早退
            $leave_time = 0;//早退时间
            $late = 0;//迟到
            $late_time = 0;//迟到时间
            $work = 0;//旷工
            $work_time = 0;//旷工时间
            $card = 0;//缺卡

            foreach ($time as $t) {
                if (empty($t['clock_in']) && !empty($t['clock_out'])) {//缺卡
                    $card += 1;
                }
                if (empty($t['clock_out']) && !empty($t['clock_in'])) {//缺卡
                    $card += 1;
                }
                if (empty($t['clock_in']) && empty($t['clock_out'])) {
                    $work += 1;
                    $end_time = strtotime(date('Y-m-d ') . $v['end_time']);
                    $start_time = strtotime(date('Y-m-d ') . $v['start_time']);
                    $end_time = $end_time > $start_time ? $end_time : $end_time + 86400;
                    //旷工时长
                    $wtime = intval(($end_time - $start_time) / 60);
                    $work_time += $wtime;
                }
                if ($t['leaver_time'] > 0) {//早退
                    $leave += 1;
                    $leave_time += $t['leaver_time'];
                }
                if ($t['late_time'] > 0) {//迟到
                    $late += 1;
                    $late_time += $t['late_time'];
                }
            }
            if($type == 'leave' && $leave_time > 0 ){//早退
                $result[]=['day'=>$day,'msg'=>'早退'.$leave_time.'分钟'];
            }
            if($type == 'late' && $late_time > 0){//迟到
                $result[]=['day'=>$day,'msg'=>'迟到'.$late_time.'分钟'];
            }
            if($type == 'work' && $work_time > 0){//旷工
                $result[]=['day'=>$day,'msg'=>'旷工'.$work_time.'分钟'];
            }
            if ($type == 'card' && $card > 0) {//缺卡
                $result[] = ['day' => $day, 'msg' => '缺卡' . $card . '次'];
            }

        }

        $this->success('请求成功',$result);
    }

    /**
     * 请假
     */
    public function leave()
    {
        $data = $this->request->post();
        if (empty($data)) {
            $this->error('数据不能为空');
        }

        try {
            //请假单
            Leave::createLeave($data);
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        $this->success('提交成功');
    }

    /**
     * 获取请假记录
     */
    public function get_leave(){
        $limit = input("limit/d", 10);
        $type=input('type');
        $cards=Leave::where(['create_staff_id'=>$this->auth->id])->order('id desc')->with(['createStaff'])->paginate($limit);

        $this->success('请求成功',$cards);
    }

    /**
     * 获取请假详情
     */
    public function get_leave_detail(){
        $id=input('id',0,'intval');

        $leave=Leave::where(['id'=>$id])->order('id desc')->with(['createStaff'])->find();
        $leave['file_ids'] = File::where(['id' => ['in', explode(',', $leave['file_ids'])]])->field('id,types,name,file_path')->select();
        //标记通知已读
        Message::setRead(Message::LEAVE_TYPE, $id, $this->auth->id);
        $this->success('请求成功',$leave);
    }
    /**
     * 计算请假时间
     */
    public function getleavetime()
    {
        $start_time = input('start_time');
        $end_time = input('end_time');
        if(empty($start_time) || empty($end_time)){
            $this->error('参数错误');
        }
        $start_time= strtotime($start_time);
        $end_time= strtotime($end_time);
        $start_date = strtotime(date('Y-m-d', $start_time));
        $end_date = strtotime(date('Y-m-d', $end_time));
        $fields = [
            1 => 'monday',
            2 => 'tuesday',
            3 => 'wednesday',
            4 => 'thursday',
            5 => 'friday',
            6 => 'saturday',
            0 => 'weekday',
        ];
        $hour=0;
        for ($start_date; $start_date <= $end_date; $start_date = $start_date + 86400) {
            $w = date('w', $start_date);
            $attendances = AttendanceTime::where([$fields[$w] => 1])->select();
            foreach ($attendances as $a) {
                $start = strtotime(date('Y-m-d ', $start_date) . $a['start_time']);
                $end = strtotime(date('Y-m-d ', $start_date) . $a['end_time']);
                $end = $start < $end ? $end : $end + 86400;
                if ($start_time < $start && $end_time > $end) {
                    $hour += ceil(($end - $start) / (60 * 60));
                }
                if ($start_time < $start && $end_time < $end) {
                    $hour += ceil(($end_time - $start) / (60 * 60));
                }
                if ($start_time > $start && $end_time > $end) {
                    $hour += ceil(($end - $start_time) / (60 * 60));
                }
                if ($start_time > $start && $end_time < $end) {
                    $hour += ceil(($end_time - $start_time) / (60 * 60));
                }

            }
        }
        $this->success('请求成功',['hour'=>$hour]);
    }
}